package regex

import (
	"encoding/json"
	"fmt"
	"regexp"
	"strings"
)

// Group 正则分组
// 一行格式为：姓名 年龄 邮箱地址的内容，将其转换为一个map
func Group() {
	str := `gaoxizhi 26 heiagaoxiang@gmail.com`

	// 使用命名分组，显得更清晰
	re := regexp.MustCompile(`(?P<name>[a-zA-Z]+)\s+(?P<age>\d+)\s+(?P<email>\w+@\w+(?:\.\w+)+)`)
	match := re.FindStringSubmatch(str)
	groupNames := re.SubexpNames()

	// 注意 groupNames [ name age email]有4个元素， 第一个为""
	fmt.Printf("%v, %v, %d, %d\n", match, groupNames, len(match), len(groupNames))

	result := make(map[string]string)

	// 转换为map
	for i, name := range groupNames {
		if i != 0 && name != "" {
			// 第一个分组为空（也就是整个匹配）
			result[name] = match[i]
		}
	}

	prettyResult, _ := json.MarshalIndent(result, "", "  ")
	fmt.Printf("%s\n", prettyResult)
}

// GroupMultipleLine 将多行格式为：姓名 年龄 邮箱地址的内容,转换为多个map的列表
// 使用命名分组可以使正则表示的意义更清晰
// 转换为map更加符合人类的阅读习惯，不过比一般的根据索引取分组值麻烦一些
func GroupMultipleLine() {
	// 文件内容直接用字符串表示
	usersStr := `
    gaoxizhi 26 gaox@gmail.com
    huanglei 23 huang@github.com
    lisa 25 li@outlook.com
`

	userRe := regexp.MustCompile(`(?P<name>[a-zA-Z]+)\s+(?P<age>\d+)\s+(?P<email>\w+@\w+(?:\.\w+)+)`)

	// 这里要用 FindAllStringSubmatch，找到所有的匹配
	users := userRe.FindAllStringSubmatch(usersStr, -1)

	groupNames := userRe.SubexpNames()
	var result []map[string]string // slice of map

	// 循环所有行
	for _, user := range users {
		m := make(map[string]string)

		// 对每一行生成一个map
		for j, name := range groupNames {
			if j != 0 && name != "" {
				m[name] = strings.TrimSpace(user[j])
			}
		}
		result = append(result, m)
	}

	prettyResult, _ := json.MarshalIndent(result, "", "  ")
	fmt.Println(string(prettyResult))
}

// GroupMultipleLineWithFor 安装匹配格式，嵌套for循环
func GroupMultipleLineWithFor() {
	var rows [2]string
	rows[0] = `<a href="access-20220115.log">access-20220115.log</a>                                15-Jan-2022 15:32                   20`
	rows[1] = `<a href="server-20220115.log">server-20220115.log</a>                                15-Jan-2022 15:32                 1023`

	for _, row := range rows {
		re := regexp.MustCompile(`>(?P<fileName>.*)</a.*>(?: +)(?P<time>\S+ \S+)(?: +)(?P<line>\d+)$`)
		match := re.FindStringSubmatch(row)
		groupNames := re.SubexpNames()
		result := make(map[string]string)

		// 转换为map
		for i, name := range groupNames {
			if i != 0 && name != "" {
				// 第一个分组为空（也就是整个匹配）
				result[name] = match[i]
			}
		}

		prettyResult, _ := json.MarshalIndent(result, "", "  ")
		fmt.Printf("%s\n", prettyResult)
	}
}
